package com.woniu.aspect;


import com.woniu.entity.Result;

import com.woniu.pojo.UserLog;
import com.woniu.service.ILogService;

import com.woniu.util.ip.AddressUtils;
import lombok.extern.slf4j.Slf4j;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;


@Aspect
@Component
@Slf4j
public class LogAspect {

    @Autowired
    private ILogService logService;

    /** 排除敏感属性字段 */
    public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };




    @Before("@annotation(oprelog)")
    public void before(Log oprelog){
        log.debug("进入了日志切面的前置通知方法=====");
    }


    @After("@annotation(oprelog)")
    public void after(Log oprelog){
        log.debug("进入了日志切面的后置通知方法=====");
    }


    @Around("@annotation(oprelog)")
    public Object around(ProceedingJoinPoint joinPoint, Log oprelog) throws Throwable {
        log.debug("进入了日志切面的环绕通知方法,开始=====");
        //执行业务的方法
        Result result = (Result) joinPoint.proceed();
        //保存日志
        UserLog operLogMin=new UserLog();
//        String name = (String) session.getAttribute("name");
        operLogMin.setUserName("Admin");
        operLogMin.setType(oprelog.type());
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        operLogMin.setMethod(className+"."+methodName);

        //获取RequestAttributes
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        //从获取RequestAttributes中获取HttpServletRequest的信息
        //客户端浏览器发出的请求被封装成为一个HttpServletRequest对象
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        //HttpSession session = request.getSession();
//        String name = (String) session.getAttribute("name");
//        operLogMin.setUserName(name);
        operLogMin.setUserIp(request.getRemoteAddr());
        String address = AddressUtils.getRealAddressByIP(request.getRemoteAddr());
        operLogMin.setLocation(address);
        operLogMin.setCreateTime(new Date());
        if (result.getCode()==200){
            operLogMin.setStatus(0);
            logService.save(operLogMin);
        }else {
            operLogMin.setStatus(1);
            logService.save(operLogMin);
        }

        log.debug("日志调用成功",operLogMin);
        log.debug("进入了日志切面的环绕通知方法,执行完了目标方法，返回值为：{}=====", result);
        return result;
    }

    @AfterThrowing(value = "@annotation(oprelog)", throwing = "exception")
    public void afterThrowing(Log oprelog, Exception exception){
        log.debug("进入了日志切面的异常通知方法=====");
    }

    @AfterReturning(value = "@annotation(oprelog)", returning = "result")
    public void afterReturning(Log oprelog, Object result){
        log.debug("进入了日志切面的返回通知方法，返回值为：{}=====", result);
    }
}
